import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;


public class Robot extends MapObject implements RobotActions {
	static int robotSize = 50;
	static int robotBorder = 10;

	String name;
	int life = 100;
	int credit = 100;
	int damaged = 0;

	public double deltaX;
	public double deltaY;

	int killedRobots = 0;
	
	Movement movement = null;
	Attack attack = null;

	// GUI
	String avatarImageFilename = null;
	Label avatar = null;

	public Robot(int x, int y, String robotName) {
		this.x = x;
		this.y = y;
		this.name = robotName;
		// GUI
		avatar = new Label(Map.getInstance().canvas, SWT.NO_BACKGROUND);
		avatar.setBounds(getX() - robotSize / 2, getY() - robotSize / 2,
				robotSize, robotSize);

		avatar.addMouseListener(new MouseListener() {

			@Override
			public void mouseUp(MouseEvent arg0) {
				// TODO Auto-generated method stub
			}

			@Override
			public void mouseDown(MouseEvent arg0) {
				System.out.println("Mouse down");
				Map.getInstance().selectRobot(Robot.this);
			}

			@Override
			public void mouseDoubleClick(MouseEvent arg0) {
				// TODO Auto-generated method stub

			}
		});
	}

	public void drawAvatar() {
		if(!avatar.isDisposed()){
			avatar.setBounds(getX() - robotSize / 2, getY() - robotSize / 2,
					robotSize, robotSize);
		}
	}

	public void setAvatarImage(String filename) {
		Image avatarImage;
		avatarImageFilename = filename;
		try {
			avatarImage = new Image(avatar.getDisplay(), avatarImageFilename);
		} catch (Exception e) {
			avatarImage = new Image(avatar.getDisplay(),
					Map.defaultImageFilename);
		}
		avatar.setImage(avatarImage);
	}

	public void setSpeed(int speed) {
		this.speed = speed;
		deltaX = speed * Math.cos(angle * Math.PI / 180);
		deltaY = speed * Math.sin(angle * Math.PI / 180);
	}

	public void setAngle(int angle) {
		this.angle = angle;
		deltaX = speed * Math.cos(angle * Math.PI / 180);
		deltaY = speed * Math.sin(angle * Math.PI / 180);
	}

	public void play() {
		credit +=2;
		
		int width = Map.getInstance().width;
		int height = Map.getInstance().height;

		// actualizar coordenada x de acordo com velocidade e angulo
		if (getX() >= 0 && getX() <= width) {
			x += deltaX;
		}

		// verificar se o robot saiu indevidamente fora do tabuleiro e
		// reposiciona-lo
		if (getX() < 0) {
			x = 0;
		} else if (getX() > width) {
			x = width;
		}

		// actualizar coordenada x de acordo com velocidade e angulo
		if (getY() >= 0 && getY() <= height) {
			y += deltaY;
		}

		// verificar se o robot saiu indevidamente fora do tabuleiro e
		// reposiciona-lo
		if (getY() < 0) {
			y = 0;
		} else if (getY() > height) {
			y = height;
		}

		if(movement!=null)
			movement.play(this);
		if(attack!=null)
			attack.play(this);

		drawAvatar();
		if (damaged > 0) {
			damaged--;
		}
	}

	public void damage(int damageValue) {
		life -= damageValue;
		damaged = 10;
	}

	public void drawDamage(GC gc) {
		if (damaged > 0) {
			gc.setBackground(avatar.getDisplay().getSystemColor(SWT.COLOR_RED));
			gc.fillRoundRectangle(getX() - (robotSize + robotBorder) / 2,
					getY() - (robotSize + robotBorder) / 2, robotSize
							+ robotBorder, robotSize + robotBorder, 30, 30);
		}
	}

	public void drawSelected(GC gc) {
		if(!avatar.isDisposed()){
		gc.setBackground(avatar.getDisplay().getSystemColor(SWT.COLOR_YELLOW));
		gc.fillRoundRectangle(getX() - (robotSize + robotBorder) / 2, getY()
				- (robotSize + robotBorder) / 2, robotSize + robotBorder,
				robotSize + robotBorder, 20, 20);
		}
	}

	public void checkLife(){
		if(life<=0){
			avatar.dispose();
			if(Map.getInstance().selectedRobot == this)
				Map.getInstance().selectedRobot  = null;
			Map.getInstance().robots.remove(this);
		}
	}
	
	/************* Robot Actions **************/

	private int abs(int op){
		if(op >0)
			return op;
		return -op;
	}
	
	@Override
	public int accelerate(int deltaSpeed) {
		int price = abs(deltaSpeed);
		if (credit >= price) {
			setSpeed((int) (this.speed + deltaSpeed));
			credit -= price;
			return 1;
		}
		
		return 0;
	}

	@Override
	public int turn(int angle) {
		setAngle(this.angle + angle);
		return 0;
	}

	@Override
	public int fire(int angle, int power, int speed) {
		int price = abs(power) + abs(speed);
		if (credit >= price) {
			credit -= price;
			Map.getInstance().fire(this, speed, angle, power);
			return 1;
		}
		return 0;
	}

	@Override
	public int add(int op1, int op2) {
		return op1 + op2;
	}

	@Override
	public int div(int op1, int op2) {
		if (op2 == 0) {
			return 0;
		}
		return op1 / op2;
	}

	@Override
	public int mul(int op1, int op2) {
		return op1 * op2;
	}

	@Override
	public int sub(int op1, int op2) {
		return op1 - op2;
	}

	@Override
	public int getCredit() {
		return this.credit;
	}

	@Override
	public int getHealth() {
		return this.life;
	}
	
	public int getSpeed() {
		return (int)this.speed;
	}

	@Override
	public int getIteration() {
		return Map.getInstance().iteration;
	}	

	@Override
	public int eq(int op1, int op2) {
		
		if (op1 == op2)
			return 1;
			
		return 0;
	}

	@Override
	public int great(int op1, int op2) {
		
		if (op1 > op2)
			return 1;
		
		return 0;
	}

	@Override
	public int less(int op1, int op2) {
		if (op1 < op2)
			return 1;
		
		return 0;
	}

	@Override
	public int scope2(int op1, int op2) {
		return op2;
	}

	@Override
	public int and(int op1, int op2) {
		if(op1!=0 && op2!=0)
			return 1;
		return 0;
	}

	@Override
	public int not(int op) {
		if(op == 0)
			return 1;
		return 0;
	}

	@Override
	public int or(int op1, int op2) {
		if(op1 == 0 && op2==0)
			return 0;
		return 1;
	}

	@Override
	public int mod(int op1, int op2) {
		if(op2 != 0)
			return op1%op2;
		return 0;
	}

	@Override
	public int scope3(int op1, int op2, int op3) {
		return op3;
	}

	@Override
	public int scope4(int op1, int op2, int op3, int op4) {
		return op4;
	}

	@Override
	public int scope5(int op1, int op2, int op3, int op4, int op5) {
		return op5;
	}

	@Override
	public int scope6(int op1, int op2, int op3, int op4, int op5, int op6) {
		return op6;
	}

	@Override
	public int getAngle() {
		return angle;
	}

	@Override
	public int getHeight() {
		return Map.getInstance().height;
	}

	@Override
	public int getWidth() {
		return Map.getInstance().width;
	}
	
	/***********************************************/
}
